package com.subalien.server;

import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.Query;

import org.apache.log4j.Logger;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.subalien.client.dto.PlayerDto;
import com.subalien.client.dto.SubmarineDto;
import com.subalien.client.jdo.Player;
import com.subalien.client.jdo.Submarine;
import com.subalien.client.service.GameService;

public class GameServiceImpl extends RemoteServiceServlet implements GameService {
	private static final long serialVersionUID = -975640146882129001L;
	private static Logger LOG = Logger.getLogger(LoginServiceImpl.class);
	private static final PersistenceManagerFactory PMF = JDOHelper.getPersistenceManagerFactory("transactions-optional");

	@Override
	public long createPlayer(String email, String name) {
		LOG.trace("createPlayer: enter");
		LOG.debug("email: " + email + ", name: " + name);
		
		PersistenceManager pm = PMF.getPersistenceManager();
		long playerId = 0;
		try {
			Player player = pm.makePersistent(new Player(email, name));
			playerId = player.getId();
		} finally {
			pm.close();
		}
		
		LOG.trace("createPlayer: exit");

		return playerId;
	}

	@Override
	public PlayerDto getPlayer(String email) {
		LOG.trace("getPlayer: enter");
		LOG.debug("email: " + email);
		
		PersistenceManager pm = PMF.getPersistenceManager();

		PlayerDto playerDto = null;
		try {
			Query q = pm.newQuery(Player.class, "email == e");
			q.declareParameters("String e");
			q.setUnique(true);
			//	      q.setOrdering("createDate");
			Player player = (Player) q.execute(email);

			if (player!=null) {
				System.out.println("Player with email: " + email + " found.");
				System.out.println("   player.getId(): " + player.getId() + ", player.getEmail(): " + player.getEmail() + 
						", player.getName(): " + player.getName() + ", player.getCreateDate(): " + player.getCreateDate());
				playerDto = new PlayerDto(player.getId(), player.getEmail(), player.getName(), player.getCreateDate());
			}
		} finally {
			pm.close();
		}

		LOG.trace("getPlayer: exit");

		return playerDto;
	}

	@Override
	public void createSubmarine(long playerId) {
		LOG.trace("createSubmarine: enter");
		LOG.debug("playerId: " + playerId);
		
		PersistenceManager pm = PMF.getPersistenceManager();
		try {
			pm.makePersistent(new Submarine(playerId));
		} finally {
			pm.close();
		}
		
		LOG.trace("createSubmarine: exit");

	}

	@Override
	public SubmarineDto getSubmarine(long playerId) {
		LOG.trace("getSubmarine: enter");
		LOG.debug("playerId: " + playerId);

		PersistenceManager pm = PMF.getPersistenceManager();

		SubmarineDto submarineDto = null;
		try {
			Query q = pm.newQuery(Submarine.class, "playerId == p");
			q.declareParameters("Long p");
			q.setUnique(true);
			Submarine submarine = (Submarine) q.execute(playerId);

			if (submarine!=null) {
				System.out.println("Submarine for playerId: " + playerId + ": " + submarine.getId());
				submarineDto = new SubmarineDto(submarine.getId(), submarine.getSubmarineType(), submarine.getName(), submarine.getLevel(), 
						submarine.getBattery());
			}
		} finally {
			pm.close();
		}
		
		LOG.trace("getSubmarine: exit");

		return submarineDto;
	}
	
	@Override
	public void updateSubmarine(SubmarineDto submarineDto) {
		LOG.trace("updateSubmarine: enter");
		LOG.debug("updateSubmarine, id: " + submarineDto.getId());

		PersistenceManager pm = PMF.getPersistenceManager();
	    try {
	        Submarine submarine = pm.getObjectById(Submarine.class, submarineDto.getId());
	        submarine.setSubmarineType(submarineDto.getSubmarineType());
	        submarine.setLevel(submarineDto.getLevel());
	        submarine.setBattery(submarineDto.getBattery());
	    } finally {
	        pm.close();
	    }
	    
		LOG.trace("updateSubmarine: exit");
	}
}
